package org.cunamas.web.controller;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.cunamas.core.bean.GeneralDataLoadErrorBean;
import org.cunamas.core.bean.PracticesInputBean;
import org.cunamas.core.service.DataLoadService;
import org.cunamas.web.util.CunamasConstants;
import org.cunamas.web.util.FileLoad;
import org.cunamas.web.util.MessagesView;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PracticesInputDataLoadController {
	
	@Autowired
	private DataLoadService dataLoadService;
	
	private ArrayList<FileLoad> files = null;
    private int uploadsAvailable = CunamasConstants.TOTAL_UPLOADS_AVAILABLE;
    
    private boolean flagLoaded;
    private String messageError;
    private String messageInfo;
    private FileLoad fileLoad = new FileLoad();
    
    private Long anio;
    
    public Long getAnio() {
		return anio;
	}

	public void setAnio(Long anio) {
		this.anio = anio;
	}

	private List<GeneralDataLoadErrorBean> generalDataLoadErrorBeanList;
    
    public void loadDefaultValues(){
    	files = new ArrayList<FileLoad>();
    	messageError = null;
    	messageInfo = null;
    	generalDataLoadErrorBeanList = null;
    	anio=null;
    }
    
    public void listener(UploadEvent event) throws Exception{
        UploadItem item = event.getUploadItem();
        FileLoad file = new FileLoad();
        file.setLength(item.getData().length);
        file.setFileName(item.getFileName());
        file.setData(item.getData());
        
        int index = file.getFileName().lastIndexOf(".");
        file.setName(file.getFileName().substring(0,index));
        
        String extension = file.getFileName().substring(file.getFileName().lastIndexOf(".")+1, file.getFileName().length());
        file.setExtension(extension);
        
        ByteArrayInputStream bis = new ByteArrayInputStream(item.getData());
        file.setUploadedFile(bis);
        
        if(files==null) files = new ArrayList<FileLoad>();
        files.add(file);
        
        uploadsAvailable--;
    }  
      
    public String clearUploadData() {
        files.clear();
        setUploadsAvailable(1);
        return null;
    }
    
    
	public void loadData(boolean onlyValidateData) {
		if (this.validateFile()) {
			this.readFile(onlyValidateData);
		}
	}
	
	private boolean validateFile() {
		messageError = null;
		messageInfo = null;
		
		String extension = null;
		
		if(files==null || files.size()==0) return false;
		fileLoad = files.get(0);
		
		if(fileLoad.getFileName() != null && fileLoad.getFileName().trim().length()>1) {
			// validar extension
			extension = fileLoad.getExtension();
			
			if(extension != null && extension.toUpperCase().equals(CunamasConstants.DATA_LOAD_EXTENSION_FILE)) {
				if(!fileLoad.isFileExist()){
					fileLoad.setPrearchivo(CunamasConstants.DATA_LOAD_INPUT_ROUTE);
					fileLoad.setFileName(fileLoad.getName() + fileLoad.getExtension() + System.currentTimeMillis());
					if(!fileLoad.saveToDisk()){
						messageError = MessagesView.getI18nMessage("general.dataLoad.validate.copy.error");
						return false;
					}
				}
			}
			else{
				messageError = MessagesView.getI18nMessage("general.validate.extension.error");
				return false;
			}
		}
		else{
			messageError = MessagesView.getI18nMessage("general.dataLoad.validate.file.null");
			return false;
		}
		
		return true;
	}
	
	private void readFile(boolean onlyValidateData) {
		
		List<PracticesInputBean> practicesInputBeanList = new ArrayList<PracticesInputBean>();
		
		Long anio = null;
		String grupoSede = null;
		String codigoUbigeo = null;
		String departamento = null;
		String provincia = null;
		String distrito = null;
		String codigoComiteGestion = null;
		String nombreComiteGestion = null;
		Long puntuacionJuego = null;
		Long puntuacionLavadoManos = null;
		Long puntuacionAlimentacionActiva = null;
		Long puntuacionCepilladoDental = null;
		
		PracticesInputBean practicesInputBean = null;
		POIFSFileSystem poifsFileSystem = null;
		
		messageError = null;
		messageInfo = null;
		String error = null;
		int col = 0;
		
		try {
			FileInputStream  fileIn = new FileInputStream(fileLoad.getPrearchivo() + fileLoad.getFileName());
			poifsFileSystem = new POIFSFileSystem(fileIn);
		}
		catch (FileNotFoundException ex) {
			ex.printStackTrace();
		}
		catch (IOException ex) {
			ex.printStackTrace();
		}
		
		HSSFWorkbook workbook;
		
		generalDataLoadErrorBeanList = new ArrayList<GeneralDataLoadErrorBean>();
		
		
		try {
			workbook = new HSSFWorkbook(poifsFileSystem);
			HSSFSheet sheet = workbook.getSheetAt(0);
			for(int i=2;i<sheet.getPhysicalNumberOfRows();i++){
				
				col = 0;

				Row row=sheet.getRow(i);
				Cell anioCell = row.getCell(col++);
				Cell grupoSedeCell = row.getCell(col++);
				Cell codigoUbigeoCell = row.getCell(col++);
				Cell departamentoCell = row.getCell(col++);
				Cell provinciaCell = row.getCell(col++);
				Cell distritoCell = row.getCell(col++);
				Cell codigoComiteGestionCell = row.getCell(col++);
				Cell nombreComiteGestionCell = row.getCell(col++);
				Cell puntuacionJuegoCell = row.getCell(col++);
				Cell puntuacionLavadoManosCell = row.getCell(col++);
				Cell puntuacionAlimentacionActivaCell = row.getCell(col++);
//				Cell puntuacionCepilladoDentalCell = row.getCell(col++);
				
				practicesInputBean = new PracticesInputBean();
				practicesInputBean.setAnio(this.anio);
				
				if (anioCell != null && anioCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
					anio = Long.valueOf((long)anioCell.getNumericCellValue());
					if(anio.compareTo(this.anio)==0){
						practicesInputBean.setAnio(this.anio);
					}
					else{
						this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessageByParameters("practicesInputDataLoad.validate.anioDifferent",this.anio.toString()));
					}
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.anioNoExist"));
				}
				
				if (grupoSedeCell != null && grupoSedeCell.getCellType() == Cell.CELL_TYPE_STRING) {
					grupoSede = grupoSedeCell.getStringCellValue();
					practicesInputBean.setGrupoSede(grupoSede);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.grupoSedeNoExist"));
				}
				
				if (codigoUbigeoCell != null && codigoUbigeoCell.getCellType() == Cell.CELL_TYPE_STRING) {
					codigoUbigeo = codigoUbigeoCell.getStringCellValue();
					practicesInputBean.setCodigoUbigeo(codigoUbigeo);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.codigoUbigeoNoExist"));
				}
				
				if (departamentoCell != null && departamentoCell.getCellType() == Cell.CELL_TYPE_STRING) {
					departamento = departamentoCell.getStringCellValue();
					practicesInputBean.setDepartamento(departamento);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.departamentoNoExist"));
				}
				
				if (provinciaCell != null && provinciaCell.getCellType() == Cell.CELL_TYPE_STRING) {
					provincia = provinciaCell.getStringCellValue();
					practicesInputBean.setProvincia(provincia);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.provinciaNoExist"));
				}
				
				if (distritoCell != null && distritoCell.getCellType() == Cell.CELL_TYPE_STRING) {
					distrito = distritoCell.getStringCellValue();
					practicesInputBean.setDistrito(distrito);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.distritoNoExist"));
				}
				
				if (codigoComiteGestionCell != null && codigoComiteGestionCell.getCellType() == Cell.CELL_TYPE_STRING) {
					codigoComiteGestion = codigoComiteGestionCell.getStringCellValue();
					practicesInputBean.setCodigoComiteGestion(codigoComiteGestion);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.codigoComiteGestionNoExist"));
				}
				
				if (nombreComiteGestionCell != null && nombreComiteGestionCell.getCellType() == Cell.CELL_TYPE_STRING) {
					nombreComiteGestion = nombreComiteGestionCell.getStringCellValue();
					practicesInputBean.setNombreComiteGestion(nombreComiteGestion);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.nombreComiteGestionNoExist"));
				}
				
				if (puntuacionJuegoCell != null && puntuacionJuegoCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
					if(puntuacionJuegoCell.getCellType()==Cell.CELL_TYPE_BLANK){
						puntuacionJuego = 0L;
					}
					else{
						puntuacionJuego = Long.valueOf((long)puntuacionJuegoCell.getNumericCellValue());
					}
					practicesInputBean.setPuntuacionJuego(puntuacionJuego);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.puntuacionJuegoNoExist"));
				}
				
				if (puntuacionLavadoManosCell != null && puntuacionLavadoManosCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
					if(puntuacionLavadoManosCell.getCellType()==Cell.CELL_TYPE_BLANK){
						puntuacionLavadoManos = 0L;
					}
					else{
						puntuacionLavadoManos = Long.valueOf((long)puntuacionLavadoManosCell.getNumericCellValue());
					}
					practicesInputBean.setPuntuacionLavadoManos(puntuacionLavadoManos);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.puntuacionLavadoManosNoExist"));
				}
				
				if (puntuacionAlimentacionActivaCell != null && puntuacionAlimentacionActivaCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
					if(puntuacionAlimentacionActivaCell.getCellType()==Cell.CELL_TYPE_BLANK){
						puntuacionAlimentacionActiva = 0L;
					}
					else{
						puntuacionAlimentacionActiva = Long.valueOf((long)puntuacionAlimentacionActivaCell.getNumericCellValue());
					}
					practicesInputBean.setPuntuacionAlimentacionActiva(puntuacionAlimentacionActiva);
				}
				else{
					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.puntuacionAlimentacionActivaNoExist"));
				}
				
//				if (puntuacionCepilladoDentalCell != null && puntuacionCepilladoDentalCell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
//					if(puntuacionCepilladoDentalCell.getCellType()==Cell.CELL_TYPE_BLANK){
//						puntuacionCepilladoDental = 0L;
//					}
//					else{
//						puntuacionCepilladoDental = Long.valueOf((long)puntuacionCepilladoDentalCell.getNumericCellValue());
//					}
//					practicesInputBean.setPuntuacionCepilladoDental(puntuacionCepilladoDental);
//				}
//				else{
//					this.addErrorMessage(generalDataLoadErrorBeanList, (i+1), MessagesView.getI18nMessage("practicesInputDataLoad.validate.puntuacionCepilladoDentalNoExist"));
//				}
				
				puntuacionCepilladoDental = 0L;
				practicesInputBean.setPuntuacionCepilladoDental(puntuacionCepilladoDental);
				
				practicesInputBeanList.add(practicesInputBean);

			}
			
			if (!onlyValidateData) {
				if (generalDataLoadErrorBeanList.size() == 0) {
					System.out.println("procesando datos = "+practicesInputBeanList.size());
					error = dataLoadService.processPracticesInputDataLoad(anio, practicesInputBeanList);
					if(error==null){
						messageInfo = MessagesView.getI18nMessage("general.validate.fileProcessed");
					}
					else{
						messageError = error;
					}
				}
			}
			else {
				if (generalDataLoadErrorBeanList == null || generalDataLoadErrorBeanList.size() == 0) {
					System.out.println("validando datos = "+practicesInputBeanList.size());
					messageInfo = MessagesView.getI18nMessage("general.validateFile.sucessfull");
				}
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
			this.addErrorMessage(generalDataLoadErrorBeanList, 0, ex.getMessage());
		}
	}
	
	private void addErrorMessage(List<GeneralDataLoadErrorBean> generalDataLoadErrorBeanList, int row, String errorMessage) {
		GeneralDataLoadErrorBean generalDataLoadErrorBean = new GeneralDataLoadErrorBean();
		
		generalDataLoadErrorBean.setRowError(row);
		generalDataLoadErrorBean.setErrorDescription(errorMessage);
		generalDataLoadErrorBeanList.add(generalDataLoadErrorBean);
	}
    
    
    public long getTimeStamp(){
        return System.currentTimeMillis();
    }

    public int getUploadsAvailable() {
        return uploadsAvailable;
    }

    public void setUploadsAvailable(int uploadsAvailable) {
        this.uploadsAvailable = uploadsAvailable;
    }

	public boolean isFlagLoaded() {
		return flagLoaded;
	}


	public void setFlagLoaded(boolean flagLoaded) {
		this.flagLoaded = flagLoaded;
	}

	public String getMessageError() {
		return messageError;
	}

	public void setMessageError(String messageError) {
		this.messageError = messageError;
	}

	public FileLoad getFileLoad() {
		return fileLoad;
	}

	public void setFileLoad(FileLoad fileLoad) {
		this.fileLoad = fileLoad;
	}

	public ArrayList<FileLoad> getFiles() {
		return files;
	}

	public void setFiles(ArrayList<FileLoad> files) {
		this.files = files;
	}


	public List<GeneralDataLoadErrorBean> getGeneralDataLoadErrorBeanList() {
		return generalDataLoadErrorBeanList;
	}


	public void setGeneralDataLoadErrorBeanList(
			List<GeneralDataLoadErrorBean> generalDataLoadErrorBeanList) {
		this.generalDataLoadErrorBeanList = generalDataLoadErrorBeanList;
	}

	public String getMessageInfo() {
		return messageInfo;
	}

	public void setMessageInfo(String messageInfo) {
		this.messageInfo = messageInfo;
	}

}